module IF(
    input clk, 
    input rst_n,
    input [1:0] PCSrc, 
    input [31:0] nextPC,
    // input flush, 
    output [31:0] Inst,
    output [31:0] PC,
    output [31:0] PC4,
    output IF_stall,
    
    output inst_sram_en,
    output [3:0] inst_sram_wen,
    output [31:0] inst_sram_addr,
    // output [31:0] inst_sram_wdada,
    input [31:0] inst_sram_rdata,

    output reg IF_addr_fault
);
    reg [31:0] PC_reg;

    // stall 1 cycle, inst  IM -> cpu
    reg inst_stall;
    wire stall = ~inst_stall;

    assign PC4 = PC_reg+4;
    assign PC = PC_reg;

    assign inst_sram_en = 1'b1;
    assign inst_sram_wen = 4'b0000;
    assign inst_sram_addr = PC_reg;
    // assign inst_sram_wdada = 0;
    // assign Inst = inst_sram_rdata & {32{inst_stall}};
    wire [31:0] fetch_Inst = inst_sram_rdata & {32{inst_stall}};
    assign Inst = fetch_Inst & {32{~IF_addr_fault}};
    
    always @(*) begin
        case (inst_sram_addr[1:0])
            2'b00:IF_addr_fault = 0;
            2'b01:IF_addr_fault = 1;
            2'b10:IF_addr_fault = 1;
            2'b11:IF_addr_fault = 1;
            default: IF_addr_fault = 0;
        endcase
    end

    always @(posedge clk) begin
        if(rst_n == 1'b0) begin
            PC_reg <= 32'hbfc00000 - 4;
            inst_stall <= 1;
        end
        else if (inst_stall) begin
            inst_stall <= inst_stall ^  1'b1;
            case (PCSrc)
                2'b00: PC_reg <= PC_reg + 4; 
                2'b01: PC_reg <= nextPC;
                2'b10 : PC_reg <= 32'hBFC00380;
                default: PC_reg <= 0;
            endcase
        end
        else if(~inst_stall) begin
            inst_stall <= inst_stall ^ 1'b1;
            PC_reg <= PC_reg;
        end
    end

    assign IF_stall = stall;
endmodule // IF